package org.yang.loginunion.core.mobile;

import org.apache.commons.lang3.StringUtils;
import org.yang.loginunion.core.LoginClient;
import org.yang.loginunion.core.constants.IdentityType;
import org.yang.loginunion.core.exception.LoginException;
import org.yang.loginunion.core.model.BindAuthCode;
import org.yang.loginunion.core.repository.OauthRepository;
import org.yang.loginunion.core.repository.OauthTempRepository;
import org.yang.loginunion.core.repository.VerifycodeRepository;

import java.util.List;
import java.util.Optional;

/**
 * 手机号+验证码登录（并绑定第三方登录信息）
 *
 * <pre>
 * 使用场景：微信APP，微信公众号登录过程中需要绑定手机号，以手机号作为系统用户必须的登录方式（如果是以邮箱作为必须的登录方式，逻辑类似）
 * </pre>
 *
 * @author Billyang
 * @date 2024/8/6 11:34
 */
public class MobileCodeBindClient implements LoginClient {

    private OauthRepository oauthRepository;
    private OauthTempRepository oauthTempRepository;
    private VerifycodeRepository verifycodeRepository;

    public MobileCodeBindClient(OauthRepository oauthRepository, OauthTempRepository oauthTempRepository,
                                VerifycodeRepository verifycodeRepository) {
        this.oauthRepository = oauthRepository;
        this.oauthTempRepository = oauthTempRepository;
        this.verifycodeRepository = verifycodeRepository;
    }

    @Override
    public String login(String mobile, String code, String bindCode) {

        if (StringUtils.isAnyBlank(mobile, code)) {
            throw new LoginException("缺失参数");
        }

        // 核对验证码
        boolean checkVerifyCode = verifycodeRepository.checkVerifycode(mobile, code);
        if (!checkVerifyCode) {
            throw new LoginException("验证码错误");
        }

        String userId = oauthRepository.getUserId(IdentityType.MOBILE, mobile);
        //获取可绑定的第三方登录方式
        BindAuthCode mobileBindAuthCode = oauthTempRepository.getBindAuthCode(bindCode);

        if (userId == null) {
            // 创建新用户
            String nickname = Optional.ofNullable(mobileBindAuthCode).map(BindAuthCode::getNickname).orElse(null);
            String avator = Optional.ofNullable(mobileBindAuthCode).map(BindAuthCode::getHeadimgurl).orElse(null);

            userId = oauthRepository.registerUser(IdentityType.MOBILE, mobile, nickname, avator);
        }

        //绑定bindCode,后续使用第三方登录的时候可以找到同一个用户
        if (mobileBindAuthCode != null) {
            List<BindAuthCode.BindUserOauth> binds = mobileBindAuthCode.getBinds();
            for (BindAuthCode.BindUserOauth bind : binds) {
                String identifier = bind.getIdentifier();
                if (StringUtils.isNotBlank(identifier)) {
                    oauthRepository.bindOauth(userId, bind.getIdentityType(), identifier, bindCode);
                }
            }
        }
        return userId;
    }
}
